﻿using System;
using System.Collections.Generic;
using System.Text;
using Core.Parser.ASN1Parser.Nodes;
using Core.Model;
using Core.Exceptions;

namespace Core.Parser.ASN1Parser.Builders
{
    internal class GroupBuilder
    {
        internal static void Build(TaggedNode node, Group group)
        {
            RootBuilder.Build(node, group);

            TaggedNode e;

            if ((e = node[ASN1ContextCodes.C_STANDARD_VERSION]) != null)
                group.StandardVersion = e.First.IntValue;

            if ((e = node[ASN1ContextCodes.C_OBJECT_INFORMATION]) != null)
                group.ObjectInformation = e.First.StringValue;

            if ((e = node[ASN1ContextCodes.C_ON_START_UP]) != null)
                group.OnStartUp = ActionBuilder.Build(e, group);

            if ((e = node[ASN1ContextCodes.C_ON_CLOSE_DOWN]) != null)
                group.OnCloseDown = ActionBuilder.Build(e, group);

            if ((e = node[ASN1ContextCodes.C_ORIGINAL_GC_PRIORITY]) != null)
                group.OriginalGroupCachePriority = e.First.IntValue;

            if ((e = node[ASN1ContextCodes.C_ITEMS]) != null)
                group.Items = BuildItems(e, group);
            else
                throw new OpenMhegException("Missing Items Block");

        }

        private static List<Ingredient> BuildItems(SequenceNode items, Group group)
        {
            var ret = new List<Ingredient>();

            foreach (TaggedNode ingredient in items)
                ret.Add(BuildItem(ingredient, group));
            
            return ret;
        }

        private static Ingredient BuildItem(TaggedNode node, Group group)
        {
            Ingredient ret = null;

            switch (node.Tag)
            {
                case (ASN1ContextCodes.C_RESIDENT_PROGRAM):
                    ret = ResidentProgramBuilder.Build(node,group);
                    break;

                //  NOT UK                  case ASN1Codes.C_REMOTE_PROGRAM:  break;
                //  NOT UK                  case ASN1Codes.C_INTERCHANGED_PROGRAM: break;
                //  NOT UK                  case ASN1Codes.C_PALETTE: break;
                //  NOT UK                  case ASN1Codes.C_FONT: break;
                //  NOT UK                  case ASN1Codes.C_CURSOR_SHAPE: break;

                case (ASN1ContextCodes.C_BOOLEAN_VARIABLE):
                    ret = VariableBuilder.BuildBoolean(node,group);
                    break;

                case (ASN1ContextCodes.C_INTEGER_VARIABLE):
                    ret = VariableBuilder.BuildInteger(node,group);
                    break;

                case (ASN1ContextCodes.C_OCTET_STRING_VARIABLE):
                    ret = VariableBuilder.BuildOctetString(node,group);
                    break;

                case (ASN1ContextCodes.C_OBJECT_REF_VARIABLE):
                    ret = VariableBuilder.BuildObjectRef(node,group);
                    break;

                case (ASN1ContextCodes.C_CONTENT_REF_VARIABLE):
                    ret = VariableBuilder.BuildContentRef(node,group);
                    break;

                case (ASN1ContextCodes.C_LINK):
                    ret = LinkBuilder.Build(node,group);
                    break;

                case (ASN1ContextCodes.C_STREAM):
                    ret = StreamBuilder.Build(node,group);
                    break;

                case (ASN1ContextCodes.C_BITMAP):
                    ret = BitmapBuilder.Build(node,group);
                    break;

                case (ASN1ContextCodes.C_LINE_ART): 
                    break;

                case (ASN1ContextCodes.C_DYNAMIC_LINE_ART):
                    ret = DynamicLineArtBuilder.Build(node,group);
                    break;

                case (ASN1ContextCodes.C_RECTANGLE):
                    ret = RectangleBuilder.Build(node,group);
                    break;

                // NOT UK                   case ASN1Codes.C_HOTSPOT: pIngredient = new MHHotSpot(); break;
                // NOT UK                   case ASN1Codes.C_SWITCH_BUTTON: pIngredient = new MHSwitchButton(); break;
                // NOT UK                   case ASN1Codes.C_PUSH_BUTTON: pIngredient = new MHPushButton(); break;
                case (ASN1ContextCodes.C_TEXT):
                    ret = TextBuilder.Build(node,group);
                    break;

                case (ASN1ContextCodes.C_ENTRY_FIELD): break;
                case (ASN1ContextCodes.C_HYPER_TEXT): break;
                case (ASN1ContextCodes.C_SLIDER): break;

                case (ASN1ContextCodes.C_TOKEN_GROUP):
                    ret = TokenGroupBuilder.Build(node,group);
                    break;
                case (ASN1ContextCodes.C_LIST_GROUP):
                    ret = ListGroupBuilder.Build(node,group);
                    break;
                default:

                    //    Logging.Log(Logging.MHLogError, "'" + pItem.GetTagNo() + "' tag not in switch");

                    throw new OpenMhegException("Unknown Ingredient");

                break;
            }

            if (ret == null)
                throw new OpenMhegException("Could not build ingredient");

            return ret;
        }
    }
}
